home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 001 / pibt3sp2.arc / PIBANSIA.PAS next >
Pascal/Delphi Source File  |  1985-09-09  |  23KB  |  503 lines

  1. (*----------------------------------------------------------------------*)
  2. (*                Emulate_ANSI  -- Controls VT100 emulation             *)
  3. (*----------------------------------------------------------------------*)
  4.  
  5. OVERLAY PROCEDURE Emulate_ANSI( VT100_Allowed : BOOLEAN );
  6.  
  7. (*----------------------------------------------------------------------*)
  8. (*                                                                      *)
  9. (*    Procedure: Emulate_ANSI                                           *)
  10. (*                                                                      *)
  11. (*    Purpose:   Controls ANSI terminal emulation                       *)
  12. (*                                                                      *)
  13. (*    Calling Sequence:                                                 *)
  14. (*                                                                      *)
  15. (*       Emulate_ANSI( VT100_allowed );                                 *)
  16. (*                                                                      *)
  17. (*          VT100_allowed --- TRUE to interpret private DEC sequences   *)
  18. (*                                                                      *)
  19. (*    Remarks:                                                          *)
  20. (*                                                                      *)
  21. (*       The ANSI and VT100 emulation are partly based upon TMODEM      *)
  22. (*       by Paul Meiners and partly upon ISP100 by Tim Krauskopf.       *)
  23. (*                                                                      *)
  24. (*       VT100/ANSI commands are interpreted directly by these          *)
  25. (*       routines -- the ANSI.SYS driver is not required and should     *)
  26. (*       probably not be used, as it will result in an unnecessary      *)
  27. (*       performance degradation.                                       *)
  28. (*                                                                      *)
  29. (*       This is by no means a complete VT100 or Ansi emulation.  It    *)
  30. (*       works well enough so that the full-screen editors EDT under    *)
  31. (*       VAX/VMS and FSE under CDC/NOS will perform properly.  That was *)
  32. (*       my primary intention.  You may want to add code to emulate     *)
  33. (*       other VT100/VT102/VT103/VT131 features not found here.  If you *)
  34. (*       do, please send me back a copy so that I can add your upgrades *)
  35. (*       to future releases of PibTerm.                                 *)
  36. (*                                                                      *)
  37. (*       Also note that this emulation assumes 25 lines on the screen.  *)
  38. (*       The VT100 only has 24.                                         *)
  39. (*                                                                      *)
  40. (*       The following variables are of central interest in the         *)
  41. (*       emulation:                                                     *)
  42. (*                                                                      *)
  43. (*         Escape_Mode     --- TRUE if processing escape sequence       *)
  44. (*         Escape_Type     --- Type of escape sequence being processed  *)
  45. (*         Escape_Number   --- Number of numeric parameters in escape   *)
  46. (*                             sequence                                 *)
  47. (*         Escape_Register --- array of numeric parameters in escape    *)
  48. (*                             sequence                                 *)
  49. (*         Escape_Str      --- stores string of escape text; used to    *)
  50. (*                             gather up a musical score for BBS Ansi.  *)
  51. (*                                                                      *)
  52. (*----------------------------------------------------------------------*)
  53.  
  54. CONST
  55.    ON   = TRUE                       (* Convenient synonym for switches *);
  56.    OFF  = FALSE                      (* Likewise                        *);
  57.  
  58. VAR
  59.    Comm_Ch             : CHAR        (* Character read from comm port   *);
  60.    Kbd_Ch              : CHAR        (* Character read from keyboard    *);
  61.    VT100_Graphics_Mode : BOOLEAN     (* TRUE if VT100 graphics mode on  *);
  62.    VT100_KeyPad        : BOOLEAN     (* TRUE if alternate keypad in use *);
  63.    Origin_Mode         : BOOLEAN     (* TRUE for region origin mode     *);
  64.    Done                : BOOLEAN     (* TRUE to stop PIBTERM            *);
  65.    B                   : BOOLEAN     (* General purpose flag            *);
  66.    Graph_Ch            : BYTE        (* Graphics character              *);
  67.    Itab                : BYTE        (* Tab stop                        *);
  68.    Tabcol              : BYTE        (* Tab column                      *);
  69.    Curcol              : BYTE        (* Current column in display       *);
  70.    Auto_Print_Mode     : BOOLEAN     (* IF auto print mode in effect    *);
  71.    Printer_Ctrl_Mode   : BOOLEAN     (* IF printer controller mode on   *);
  72.    Print_Line          : STRING[80]  (* Line to print if print mode on  *);
  73.    Reg_Val             : INTEGER     (* General utility register value  *);
  74.  
  75.    Escape_Mode         : BOOLEAN     (* If processing escape sequence   *);
  76.    Escape_Number       : INTEGER     (* # of numeric parms in esc seq.  *);
  77.  
  78.                                      (* Holds numeric parms in esc seq  *)
  79.    Escape_Register     : ARRAY[1..50] OF BYTE;
  80.    Escape_Str          : AnyStr      (* Collects string arg in esc seq  *);
  81.    Escape_Type         : CHAR        (* Type of escape seq. being done  *);
  82.  
  83.                                      (* Remember cursor/attributes      *)
  84.    Save_Row_Position   : INTEGER;
  85.    Save_Col_Position   : INTEGER;
  86.    Save_BG_Color       : INTEGER;
  87.    Save_FG_Color       : INTEGER;
  88.                                      (* Save current scrolling region   *)
  89.    Top_Scroll          : INTEGER;
  90.    Bottom_Scroll       : INTEGER;
  91.  
  92.    Ansi_ForeGround_Color : INTEGER   (* Global foreground color here    *);
  93.    Ansi_BackGround_Color : INTEGER   (* Global background color here    *);
  94.    Ansi_Underline_Color  : INTEGER   (* Color for underlines            *);
  95.    Ansi_Bold_Color       : INTEGER   (* Color for bolding               *);
  96.  
  97.    FG                    : INTEGER   (* Foreground color                *);
  98.    BG                    : INTEGER   (* Background color                *);
  99.    White_Shade           : INTEGER   (* Current shade of white          *);
  100.  
  101.    Save_Global_FG        : INTEGER   (* Save global foreground color    *);
  102.    Save_Global_BG        : INTEGER   (* Save global background color    *);
  103.    Save_FG               : INTEGER   (* Save foreground color           *);
  104.    Save_BG               : INTEGER   (* Save background color           *);
  105.  
  106.    Double_Width_Mode     : BOOLEAN   (* Double width characters         *);
  107.  
  108. CONST                                (* Special VT100 graphics chars    *)
  109.  
  110.    Graphics_Chars: ARRAY[ 95 .. 126 ] Of BYTE
  111.                    = (  32,   4, 177,   9,  12,  13,  10, 248, 241,
  112.                         10,  10, 217, 191, 218, 192, 197, 196, 196,
  113.                        196, 196,  95, 195, 180, 193, 194, 179, 243,
  114.                        242, 227, 168, 156, 250 );
  115.  
  116.                                      (* VT100 tabs stops                *)
  117.    Number_VT100_Tabs = 16;
  118.  
  119.    VT100_Tabs:  ARRAY[ 1 .. Number_VT100_Tabs ] Of BYTE
  120.                = (  9, 17, 25, 33, 41, 49, 57, 65, 73, 74, 75, 76, 77,
  121.                    78, 79, 80 );
  122.  
  123. (* ------------------------------------------------------------------------ *)
  124. (*               PibPlaySet --- Set up to play music                        *)
  125. (*               PibPlay    --- Play Music through Speaker                  *)
  126. (* ------------------------------------------------------------------------ *)
  127.  
  128. PROCEDURE PibPlaySet;
  129.  
  130. (* ------------------------------------------------------------------------ *)
  131. (*                                                                          *)
  132. (*   Procedure:  PibPlaySet                                                 *)
  133. (*                                                                          *)
  134. (*   Purpose:    Sets up to play music though PC's speaker                  *)
  135. (*                                                                          *)
  136. (*   Calling Sequence:                                                      *)
  137. (*                                                                          *)
  138. (*      PibPlaySet;                                                         *)
  139. (*                                                                          *)
  140. (*   Calls:  None                                                           *)
  141. (*                                                                          *)
  142. (* ------------------------------------------------------------------------ *)
  143.  
  144. BEGIN (* PibPlaySet *)
  145.  
  146.                                    (* Default Octave *)
  147.    Note_Octave   := 4;
  148.                                    (* Default sustain is semi-legato *)
  149.    Note_Fraction := 0.875;
  150.                                    (* Note is quarter note by default *)
  151.    Note_Length   := 0.25;
  152.                                    (* Moderato pace by default *)
  153.    Note_Quarter  := 500.0;
  154.  
  155. END   (* PibPlaySet *);
  156.  
  157. PROCEDURE PibPlay( S : AnyStr );
  158.  
  159. (* ------------------------------------------------------------------------ *)
  160. (*                                                                          *)
  161. (*   Procedure:  PibPlay                                                    *)
  162. (*                                                                          *)
  163. (*   Purpose:    Play music though PC's speaker                             *)
  164. (*                                                                          *)
  165. (*   Calling Sequence:                                                      *)
  166. (*                                                                          *)
  167. (*      PibPlay( Music_String : AnyStr );                                   *)
  168. (*                                                                          *)
  169. (*         Music_String --- The string containing the encoded music to be   *)
  170. (*                          played.  The format is the same as that of the  *)
  171. (*                          MicroSoft Basic PLAY Statement.  The string     *)
  172. (*                          must be <= 254 characters in length.            *)
  173. (*                                                                          *)
  174. (*   Calls:  Sound                                                          *)
  175. (*           GetInt  (Internal)                                             *)
  176. (*                                                                          *)
  177. (*   Remarks:  The characters accepted by this routine are:                 *)
  178. (*                                                                          *)
  179. (*             A - G       Musical Notes                                    *)
  180. (*             # or +      Following A - G note,  indicates sharp           *)
  181. (*             -           Following A - G note,  indicates flat            *)
  182. (*             <           Move down one octave                             *)
  183. (*             >           Move up one octave                               *)
  184. (*             .           Dot previous note (extend note duration by 3/2)  *)
  185. (*             MN          Normal duration (7/8 of interval between notes)  *)
  186. (*             MS          Staccato duration                                *)
  187. (*             ML          Legato duration                                  *)
  188. (*             Ln          Length of note (n=1-64; 1=whole note,            *)
  189. (*                                         4=quarter note, etc.)            *)
  190. (*             Pn          Pause length (same n values as Ln above)         *)
  191. (*             Tn          Tempo, n=notes/minute (n=32-255, default n=120)  *)
  192. (*             On          Octave number (n=0-6, default n=4)               *)
  193. (*             Nn          Play note number n (n=0-84)                      *)
  194. (*                                                                          *)
  195. (*             The following two commands are IGNORED by PibPlay:           *)
  196. (*                                                                          *)
  197. (*             MF          Complete note before continuing                  *)
  198. (*             MB          Another process may begin before speaker is      *)
  199. (*                         finished playing note                            *)
  200. (*                                                                          *)
  201. (*   IMPORTANT --- PibPlaySet MUST have been called at least once before    *)
  202. (*                 this routine is called.                                  *)
  203. (*                                                                          *)
  204. (* ------------------------------------------------------------------------ *)
  205.  
  206. CONST
  207.                                    (* Offsets in octave of natural notes *)
  208.  
  209.    Note_Offset   : ARRAY[ 'A'..'G' ] OF INTEGER
  210.                    = ( 9, 11, 0, 2, 4, 5, 7 );
  211.  
  212.                                    (* Frequencies for 7 octaves *)
  213.  
  214.    Note_Freqs: ARRAY[ 0 .. 84 ] OF INTEGER
  215.                =
  216. (*
  217.       C    C#     D    D#     E     F    F#     G    G#     A    A#     B
  218. *)
  219. (     0,
  220.      65,   69,   73,   78,   82,   87,   92,   98,  104,  110,  116,  123,
  221.     131,  139,  147,  156,  165,  175,  185,  196,  208,  220,  233,  247,
  222.     262,  278,  294,  312,  330,  350,  370,  392,  416,  440,  466,  494,
  223.     524,  556,  588,  624,  660,  700,  740,  784,  832,  880,  932,  988,
  224.    1048, 1112, 1176, 1248, 1320, 1400, 1480, 1568, 1664, 1760, 1864, 1976,
  225.    2096, 2224, 2352, 2496, 2640, 2800, 2960, 3136, 3328, 3520, 3728, 3952,
  226.    4192, 4448, 4704, 4992, 5280, 5600, 5920, 6272, 6656, 7040, 7456, 7904  );
  227.  
  228.    Quarter_Note = 0.25;            (* Length of a quarter note *)
  229.  
  230.  
  231. VAR
  232.                                    (* Frequency of note to be played *)
  233.    Play_Freq     : INTEGER;
  234.  
  235.                                    (* Duration to sound note *)
  236.    Play_Duration : INTEGER;
  237.  
  238.                                    (* Duration of rest after a note *)
  239.    Rest_Duration : INTEGER;
  240.  
  241.                                    (* Offset in Music string *)
  242.    I             : INTEGER;
  243.                                    (* Current character in music string *)
  244.    C             : CHAR;
  245.                                    (* Note Frequencies *)
  246.  
  247.    Freq          : ARRAY[ 0 .. 6 , 0 .. 11 ] OF INTEGER ABSOLUTE Note_Freqs;
  248.  
  249.    N             : INTEGER;
  250.    XN            : REAL;
  251.    K             : INTEGER;
  252.  
  253. (* ------------------------------------------------------------------------ *)
  254.  
  255. FUNCTION GetInt : INTEGER;
  256.  
  257. (*   --- Get integer from music string --- *)
  258.  
  259. VAR
  260.    N : INTEGER;
  261.  
  262. BEGIN (* GetInt *)
  263.  
  264.    N := 0;
  265.  
  266.    WHILE( S[I] In ['0'..'9'] ) DO
  267.       BEGIN
  268.          N := N * 10 + ORD( S[I] ) - ORD('0');
  269.          I := I + 1;
  270.       END;
  271.  
  272.    I      := I - 1;
  273.  
  274.    GetInt := N;
  275.  
  276. END   (* GetInt *);
  277.  
  278. (* ------------------------------------------------------------------------ *)
  279.  
  280. BEGIN (* PibPlay *)
  281.                                    (* Append blank to end of music string *)
  282.    S := S + ' ';
  283.                                    (* Point to first character in music *)
  284.    I := 1;
  285.                                    (* BEGIN loop over music string *)
  286.    WHILE( I < LENGTH( S ) ) DO
  287.  
  288.       BEGIN (* Interpret Music *)
  289.                                    (* Get next character in music string *)
  290.          C := UpCase(S[I]);
  291.                                    (* Interpret it                       *)
  292.          CASE C OF
  293.  
  294.             'A'..'G' : BEGIN (* A Note *)
  295.  
  296.                           N         := Note_Offset[ C ];
  297.  
  298.                           Play_Freq := Freq[ Note_Octave , N ];
  299.  
  300.                           XN := Note_Quarter * ( Note_Length / Quarter_Note );
  301.  
  302.                           Play_Duration := TRUNC( XN * Note_Fraction );
  303.  
  304.                           Rest_Duration := TRUNC( XN * ( 1.0 - Note_Fraction ) );
  305.  
  306.                                    (* Check for sharp/flat *)
  307.  
  308.                           IF S[I+1] In ['#','+','-' ] THEN
  309.                              BEGIN
  310.  
  311.                                 I := I + 1;
  312.  
  313.                                 CASE S[I] OF
  314.                                    '#' : Play_Freq :=
  315.                                             Freq[ Note_Octave , N + 1 ];
  316.                                    '+' : Play_Freq :=
  317.                                             Freq[ Note_Octave , N + 1 ];
  318.                                    '-' : Play_Freq :=
  319.                                             Freq[ Note_Octave , N - 1 ];
  320.                                    ELSE  ;
  321.                                 END (* Case *);
  322.  
  323.                              END;
  324.  
  325.                                    (* Check for note length *)
  326.  
  327.                           IF S[I+1] In ['0'..'9'] THEN
  328.                              BEGIN
  329.  
  330.                                 I  := I + 1;
  331.                                 N  := GetInt;
  332.                                 XN := ( 1.0 / N ) / Quarter_Note;
  333.  
  334.                                 Play_Duration :=
  335.                                     TRUNC( Note_Fraction * Note_Quarter * XN );
  336.  
  337.                                 Rest_Duration :=
  338.                                    TRUNC( ( 1.0 - Note_Fraction ) *
  339.                                           Xn * Note_Quarter );
  340.  
  341.                              END;
  342.                                    (* Check for dotting *)
  343.  
  344.                              IF S[I+1] = '.' THEN
  345.                                 BEGIN
  346.  
  347.                                    XN := 1.0;
  348.  
  349.                                    WHILE( S[I+1] = '.' ) DO
  350.                                       BEGIN
  351.                                          XN := XN * 1.5;
  352.                                          I  := I + 1;
  353.                                       END;
  354.  
  355.                                    Play_Duration :=
  356.                                        TRUNC( Play_Duration * XN );
  357.  
  358.                                 END;
  359.  
  360.                                        (* Play the note *)
  361.  
  362.                           Sound( Play_Freq );
  363.                           Delay( Play_Duration );
  364.                           NoSound;
  365.                           Delay( Rest_Duration );
  366.  
  367.                        END   (* A Note *);
  368.  
  369.             'M'      : BEGIN (* 'M' Commands *)
  370.  
  371.                           I := I + 1;
  372.                           C := S[I];
  373.  
  374.                           Case C Of
  375.  
  376.                              'F' : ;
  377.                              'B' : ;
  378.                              'N' : Note_Fraction := 0.875;
  379.                              'L' : Note_Fraction := 1.000;
  380.                              'S' : Note_Fraction := 0.750;
  381.                              ELSE ;
  382.  
  383.                           END (* Case *);
  384.  
  385.  
  386.                        END   (* 'M' Commands *);
  387.  
  388.             'O'      : BEGIN (* Set Octave *)
  389.  
  390.                           I := I + 1;
  391.                           N := ORD( S[I] ) - ORD('0');
  392.  
  393.                           IF ( N < 0 ) OR ( N > 6 ) THEN N := 4;
  394.  
  395.                           Note_Octave := N;
  396.  
  397.                        END   (* Set Octave *);
  398.  
  399.             '<'      : BEGIN (* Drop an octave *)
  400.  
  401.                           IF Note_Octave > 0 THEN
  402.                              Note_Octave := Note_Octave - 1;
  403.  
  404.                        END   (* Drop an octave *);
  405.  
  406.             '>'      : BEGIN (* Ascend an octave *)
  407.  
  408.                           IF Note_Octave < 6 THEN
  409.                              Note_Octave := Note_Octave + 1;
  410.  
  411.                        END   (* Ascend an octave *);
  412.  
  413.             'N'      : BEGIN (* Play Note N *)
  414.  
  415.                           I := I + 1;
  416.  
  417.                           N := GetInt;
  418.  
  419.                           IF ( N > 0 ) AND ( N <= 84 ) THEN
  420.                              BEGIN
  421.  
  422.                                 Play_Freq    := Note_Freqs[ N ];
  423.  
  424.                                 XN           := Note_Quarter *
  425.                                                 ( Note_Length / Quarter_Note );
  426.  
  427.                                 Play_Duration := TRUNC( XN * Note_Fraction );
  428.  
  429.                                 Rest_Duration := TRUNC( XN * ( 1.0 - Note_Fraction ) );
  430.  
  431.                              END
  432.  
  433.                           ELSE IF ( N = 0 ) THEN
  434.                              BEGIN
  435.  
  436.                                 Play_Freq     := 0;
  437.                                 Play_Duration := 0;
  438.                                 Rest_Duration :=
  439.                                    TRUNC( Note_Fraction * Note_Quarter *
  440.                                           ( Note_Length / Quarter_Note ) );
  441.  
  442.                              END;
  443.  
  444.                           Sound( Play_Freq );
  445.                           Delay( Play_Duration );
  446.                           NoSound;
  447.                           Delay( Rest_Duration );
  448.  
  449.                        END   (* Play Note N *);
  450.  
  451.             'L'      : BEGIN (* Set Length of Notes *)
  452.  
  453.                           I := I + 1;
  454.                           N := GetInt;
  455.  
  456.                           IF N > 0 THEN Note_Length := 1.0 / N;
  457.  
  458.                        END   (* Set Length of Notes *);
  459.  
  460.             'T'      : BEGIN (* # of quarter notes in a minute *)
  461.  
  462.                           I := I + 1;
  463.                           N := GetInt;
  464.  
  465.                           Note_Quarter := ( 1092.0 / 18.2 / N ) * 1000.0;
  466.  
  467.                        END   (* # of quarter notes in a minute *);
  468.  
  469.             'P'      : BEGIN (* Pause *)
  470.  
  471.                           I := I + 1;
  472.                           N := GetInt;
  473.  
  474.                           IF      ( N <  1 ) THEN N := 1
  475.                           ELSE IF ( N > 64 ) THEN N := 64;
  476.  
  477.                           Play_Freq     := 0;
  478.                           Play_Duration := 0;
  479.                           Rest_Duration :=
  480.                              TRUNC( ( ( 1.0 / N ) / Quarter_Note )
  481.                                     * Note_Quarter );
  482.  
  483.                           Sound( Play_Freq );
  484.                           Delay( Play_Duration );
  485.                           NoSound;
  486.                           Delay( Rest_Duration );
  487.  
  488.                        END   (* Pause *);
  489.  
  490.             ELSE
  491.                (* Ignore other stuff *);
  492.  
  493.          END (* Case *);
  494.  
  495.          I := I + 1;
  496.  
  497.        END  (* Interpret Music *);
  498.  
  499.                                    (* Make sure sound turned off when through *)
  500.    NoSound;
  501.  
  502. END   (* PibPlay *);
  503.